﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using HouodeFun.TrainCenter.Model;
using System.Data.Objects.DataClasses;
using HouodeFun.TrainCenter.DAL;
using HouodeFun.TrainCenter.IDAL;

namespace HouodeFun.TrainCenter.BLL
{
    /// <summary>
    /// 业务逻辑层服务的基类
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public abstract class BaseService<T> where T: class,new()
    {
        #region 获取当前数据库访问的入口
        /// <summary>
        /// 数据库访问层的入口工厂的实现
        /// </summary>
        private IDbSessionFactory _DbSessionFactory;

        //获取 实体工厂，以抽象工厂的方式返回
        public IDbSessionFactory DbSessionFactory
        {
            get
            {
                if (_DbSessionFactory == null)
                {
                    //所以在此处，可以根据配置文件 反射创建实体工厂
                    _DbSessionFactory = new DbSessionFactory();
                }
                return _DbSessionFactory;
            }
            set { _DbSessionFactory = value; }
        }


        /// <summary>
        /// 数据库访问的统一入口
        /// </summary>
        private IDbSession _DbSessionContext;

        /// <summary>
        /// 获得 某一个 具体操作数据库的 数据操作上下文对象(可以访问操作数据库里所有的数据)
        /// </summary>
        //创建 实体产品，以抽象产品的方式返回
        public IDbSession DbSessionContext
        {
            get
            {
                if (_DbSessionContext == null)
                {
                    _DbSessionContext = DbSessionFactory.GetCurrentDbSession();
                }
                return _DbSessionContext;
            }
            set { _DbSessionContext = value; }
        }
        #endregion

        #region 设置当前的仓储的接口

        /// <summary>
        /// 处理当前请求的仓储
        /// 因为当前仓储是谁，我们在父类里面不知道。
        /// </summary>
        protected IBaseRepository<T> CurrentRepository;
        /// <summary>
        /// 定义一个纯的抽象方法，子类在实现此父类的时候，必须重写当前的抽象方法。
        /// </summary>
        /// <returns></returns>
        public abstract bool SetCurrentRepository();

        /// <summary>
        /// 在父类的构造函数内部，调用子类的抽象方法，那子类里面必须实现此构造方法，也就是把当前操作的 仓储赋值，然后供其他的增加、删除、修改使用
        /// </summary>
        public BaseService()
        {
            this.SetCurrentRepository();
        }

        #endregion


        //protected IBaseRepository<T> CurrentRepository

        /// <summary>
        /// 添加方法
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public T AddEntity(T entity)
        {
            //看我的blog ： EF POCO功能4.0    EF4.1以后加 CodeOnly :4.2/3
            //DbSessionContext.UserInfoRepository.AddEntity(entity);

            //这时候要获取当前要处理当前请求的仓储实例，但是
            //我们不知具体由谁来处理，只能在子类里才能知道
            //所以只能在子类里面做赋值的操作，比如在子类实例化的时候通过
            //构造函数赋值当前的仓储的实例
            //this.DbSessionContext.UserInfoRepository.AddEntity(entity);

            //this.CurrentRepository.AddEntity(entity);
            //this.DbSessionContext.BrandRepository.AddEnties(entity);


            DbSessionContext.SaveChange();
            return entity;            
        }

        /// <summary>
        /// 删除的方法
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public bool DeleteEntity(T entity)
        {
            bool result = false;
            this.CurrentRepository.DeleteEntity(entity);
            if (DbSessionContext.SaveChange() > 0)
            {
                result = true; 
            }
            return result;

        }

        public int DeleteBy(System.Linq.Expressions.Expression<Func<T, bool>> whereLambda)
        {
            return this.CurrentRepository.DeleteBy(whereLambda);
        }


        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public T UpdateEntity(T entity)
        {
            this.CurrentRepository.UpdateEntity(entity);
            if (this.DbSessionContext.SaveChange() <= 0)
            {
                return null;
            }
            return entity;
        }
         
        /// <summary>
        /// 查询多条
        /// </summary>
        /// <param name="whereLambda"></param>
        /// <returns></returns>
        public IQueryable<T> LoadEntities(System.Linq.Expressions.Expression<Func<T,bool>> whereLambda)
        {
            return this.CurrentRepository.LoadEntities(whereLambda);
        }

        /// <summary>
        /// 分页的查询
        /// </summary>
        /// <typeparam name="S"></typeparam>
        /// <param name="whereLambda"></param>
        /// <param name="orderBy"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="totalCount"></param>
        /// <param name="isAsc"></param>
        /// <returns></returns>
        public IQueryable<T> LoadPageEntities<S>(System.Linq.Expressions.Expression<Func<T, bool>> whereLambda,System.Linq.Expressions.Expression<Func<T,S>> orderBy,int pageIndex,int pageSize,out int totalCount,bool isAsc)
        {
            return this.CurrentRepository.LoadPageEntities<S>(
                whereLambda,
                orderBy,
                pageSize,
                pageIndex,
                out totalCount,
                isAsc);

        }

    }
}
